import Vue from 'vue'
import App from './App.vue'
import store from './store'
import {
  renderWithQiankun,
  qiankunWindow
} from 'vite-plugin-qiankun/dist/helper'
// import router from './router'
import ElementUI, { Table } from 'element-ui'
import pageCom from '@common/page/pageCom' // 分页组件
import freshCom from '@common/refreshBtn/freshCom' //刷新组件
import 'element-ui/lib/theme-chalk/index.css'
import '../static/css/style.css'
import '../static/css/font-awesome.min.css'
import 'jquery'
import routeConvert from '@/utils/load-router'
import * as moment from 'moment'
import * as echarts from 'echarts'
import VueClipboard from 'vue-clipboard2'
import mavonEditor from 'mavon-editor' //markdown编辑器
import 'mavon-editor/dist/css/index.css'
import {
  pubRequire,
  pubRequireFree,
  reqUrl,
  changeToForm,
  alertPower,
  getImgUrl,
  request,
  downFile
} from '@utils/public'
import * as appletPublic from '@utils/appletPublic.js'
import * as message from '@utils/msgPublic.js'
import * as filters from '@utils/filters.js'

// 解决 ElTable 自动宽度高度导致的「ResizeObserver loop limit exceeded」问题
const fixElTableErr = (table) => {
  const oldResizeListener = table.methods.resizeListener
  table.methods.resizeListener = function() {
    window.requestAnimationFrame(oldResizeListener.bind(this))
  }
}

// 一定要在Vue.use之前执行此函数
fixElTableErr(Table)

Object.keys(filters).forEach((key) => {
  // 过滤器挂载在Vue上
  Vue.filter(key, filters[key])
})

Vue.prototype.pubRequire = pubRequire
Vue.prototype.msgRequire = message.pubRequire
Vue.prototype.pubRequireApplet = appletPublic.pubRequire
Vue.prototype.pubRequireFree = pubRequireFree
Vue.prototype.request = request
Vue.prototype.reqUrl = reqUrl
Vue.prototype.getImgUrl = getImgUrl
Vue.prototype.changeToForm = changeToForm
Vue.prototype.alertPower = alertPower
Vue.prototype.downFile = downFile
Vue.prototype.downFileApplet = appletPublic.downFile
Vue.prototype.msgDown = message.downFile
Vue.prototype.echarts = echarts
Vue.prototype.moment = moment

Vue.use(ElementUI)
Vue.use(pageCom)
Vue.use(freshCom)
Vue.use(VueClipboard)
Vue.use(mavonEditor)

let instance = null
let router = null

/**
 * 渲染函数
 * 两种情况：主应用生命周期钩子中运行 / 微应用单独启动时运行
 */
function render(props) {
  // console.log(router)
  instance = new Vue({
    router,
    store,
    render: (h) => h(App)
  }).$mount('#app')
}

// 独立运行时，直接挂载应用
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render()
}

/**
 * 自定义按钮指令
 */
Vue.directive('permission', {
  inserted(el, binding) {
    const { value } = binding
    if (value) {
      const buttonList = store.getters.permsListGetters
      const hasPermission = buttonList.some((item) => {
        return item === value
      })
      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  }
})

/**
 * bootstrap 只会在微应用初始化的时候调用一次，下次微应用重新进入时会直接调用 mount 钩子，不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化，比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
  // console.log('yunying bootstraped')
}
/**
 * 应用每次进入都会调用 mount 方法，通常我们在这里触发应用的渲染方法
 */
export async function mount(props) {
  // console.log('yunying mount', props)
  store.commit('appendPermsList', props.perms)
  props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    // sessionStorage.setItem('menuName', state.activeMenus)
    if (state.activeUrl.startsWith('/yunying')) {
      router.push(state.activeUrl.replace(/\/yunying/, ''))
    }
  })
  Vue.prototype.setGlobalState = (state) => {
    props.setGlobalState(state)
  }
  router = require('./router').default
  const routers = routeConvert(props.routes)
  router.addRoutes(routers)
  router.options.routes = router.options.routes.concat(routers)
  render(props)
}

/**
 * 应用每次 切出/卸载 会调用的方法，通常在这里我们会卸载微应用的应用实例
 */
export async function unmount() {
  // store.commit('setUserInfo', null)
  // sessionStorage.removeItem('editableTabs')
  console.log('yunying unmount')
  instance.$destroy()
  instance = null
  router = null
}

renderWithQiankun({
  /**
   * bootstrap 只会在微应用初始化的时候调用一次，下次微应用重新进入时会直接调用 mount 钩子，不会再重复触发 bootstrap。
   * 通常我们可以在这里做一些全局变量的初始化，比如不会在 unmount 阶段被销毁的应用级别的缓存等。
   */
  bootstrap() {
    // console.log('yunying bootstraped')
  },
  /**
   * 应用每次进入都会调用 mount 方法，通常我们在这里触发应用的渲染方法
   */
  mount(props) {
    // console.log('yunying mount', props)
    store.commit('appendPermsList', props.perms)
    props.onGlobalStateChange((state, prev) => {
      // state: 变更后的状态; prev 变更前的状态
      // sessionStorage.setItem('menuName', state.activeMenus)
      if (state.activeUrl.startsWith('/yunying')) {
        router.push(state.activeUrl.replace(/\/yunying/, ''))
      }
    })
    Vue.prototype.setGlobalState = (state) => {
      props.setGlobalState(state)
    }
    router = require('./router').default
    const routers = routeConvert(props.routes)
    router.addRoutes(routers)
    router.options.routes = router.options.routes.concat(routers)
    render(props)
  },

  /**
   * 应用每次 切出/卸载 会调用的方法，通常在这里我们会卸载微应用的应用实例
   */
  unmount() {
    // store.commit('setUserInfo', null)
    // sessionStorage.removeItem('editableTabs')
    console.log('yunying unmount')
    instance.$destroy()
    instance = null
    router = null
  }
})
// new Vue({
//   el: '#app',
//   store,
//   router,
//   render: (h) => h(App)
// })
